import {
  Component,
  OnInit,
  Inject,
  PLATFORM_ID,
  ViewChild,
  OnDestroy
} from "@angular/core";
import { FormControl } from "@angular/forms";
import { LocaleService, TranslationService, Language } from "angular-l10n";

import { MatPaginator, MatSort, MatTableDataSource } from "@angular/material";
import {
  AssetsItem,
  ISelectAssetsRequest,
  IFindDepositAddressRequest,
  IFindAssetsResponseData
} from "@/assets/store/models/assets";
import { Store, select } from "@ngrx/store";
import * as fromUser from "@/user/store/reducers/index";
import * as fromTrade from "@/trade/store/reducers/index";
import * as fromAssets from "@/assets/store/reducers/index";
import * as fromRoot from "@/reducers/index";
import { map, filter, skip } from "rxjs/operators";
import { Subscription } from "rxjs";
import { AssetsActions } from "@/assets/store/actions";
import { forkJoin, combineLatest, zip } from "rxjs";
import { combineAll, debounceTime } from "rxjs/operators";
import { Router, NavigationEnd } from "@angular/router";
import { ActivatedRoute } from "@angular/router";
import { isPlatformServer } from "@angular/common";

const QRCode = require("qrcode");

@Component({
  selector: "app-deposit",
  templateUrl: "./deposit.component.html",
  styleUrls: ["./deposit.component.scss"]
})
export class DepositComponent implements OnInit, OnDestroy {
  public address: FormControl = new FormControl();
  @Language() lang: string;

  search: FormControl = new FormControl();

  depositAddress$ = this.store.pipe(
    select(fromRoot.depositAddress),
    filter(depositAddress => !!depositAddress)
  );

  req: IFindDepositAddressRequest = {
    coin: ""
  };

  assets$ = this.store
    .pipe(select(fromRoot.assets))
    .pipe(filter(assets => !!assets));

  assets: IFindAssetsResponseData = {
    coin: "",
    total: "",
    ava: "",
    frozen: "",
    point: 0,
    feeRatio: "",
    baseFee: "",
    withdraw: {
      min: "",
      max: ""
    },
    deposit: {
      min: "",
      confirm: ""
    }
  };

  user$ = this.store.pipe(
    select(fromRoot.user),
    filter(user => !!user)
  );

  sub$ = {
    assetsSub$: null,
    depositAddressSub$: null,
    userAndQuerySub$: null,
    querySub$: null
  };

  query = {
    coin: ""
  };

  isServer = true;
  @ViewChild("qrcode")
  qrcode;
  constructor(
    @Inject("MsgService") private msgService,
    @Inject("UtilsService") private utilsService,
    private store: Store<
      fromTrade.State | fromUser.State | fromAssets.State | fromRoot.State
    >,
    private router: Router,
    private activatedRoute: ActivatedRoute,
    @Inject(PLATFORM_ID) private platformId: Object
  ) {
    this.isServer = isPlatformServer(this.platformId);
  }

  ngOnInit() {
    this.addListen();
  }

  addListen() {
    this.sub$.userAndQuerySub$ = combineLatest(
      this.user$,
      this.activatedRoute.queryParams
    ).subscribe(([user, query]) => {
      const { coin } = query;
      if (!!coin) {
        const findAssets = new AssetsActions.FindAssets({
          req: {
            coin,
            uid: user.id
          }
        });
        this.store.dispatch(findAssets);
      }
    });

    this.sub$.querySub$ = this.activatedRoute.queryParams.subscribe(query => {
      const { coin } = query;
      this.query.coin = coin;
      this.req.coin = coin;

      this.store.dispatch(
        new AssetsActions.FindDepositAddress({
          req: { ...this.req },
          cpt: this
        })
      );
    });

    this.sub$.depositAddressSub$ = this.depositAddress$.subscribe(e => {
      this.address.setValue(e);
      if (!this.isServer) {
        QRCode.toCanvas(this.qrcode.nativeElement, e, { version: 4 }, function(
          error
        ) {});
      }
    });

    this.sub$.assetsSub$ = this.assets$.subscribe(e => {
      this.assets = e;
    });
  }

  onChangeCoin(e) {
    if (e.coin !== this.query.coin) {
      this.router.navigate(["/assets/deposit"], {
        queryParams: {
          coin: e.coin
        }
      });
    }
  }

  onSuccessCopy() {
    this.msgService.success("success");
  }

  ngOnDestroy() {
    this.utilsService.unsub(this.sub$);
  }
}
